import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import mplfinance as mpf

# 设置中文字体，确保图形中的中文正常显示
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS', 'Microsoft YaHei']
plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题

class BYDStockAnalysis:
    def __init__(self, file_path):
        # 读取Excel文件
        self.df = pd.read_excel(file_path)
        # 确保日期列格式正确
        if '日期' in self.df.columns:
            self.df['日期'] = pd.to_datetime(self.df['日期'])
            self.df.set_index('日期', inplace=True)
        print("数据读取完成！")
    
    def inspect_data(self):
        # 观察数据形状
        print(f"数据形状: {self.df.shape}")
        # 输出数据前5行
        print("\n数据前5行:")
        print(self.df.head())
        # 对定量变量进行描述性分析
        print("\n定量变量描述性分析:")
        descriptive_stats = self.df.describe()
        print(descriptive_stats)
        return descriptive_stats
    
    def calculate_correlation(self):
        # 选择数值型列计算相关系数
        numeric_columns = self.df.select_dtypes(include=['float64', 'int64']).columns
        correlation_matrix = self.df[numeric_columns].corr()
        print("\n变量相关系数矩阵:")
        print(correlation_matrix)
        
        # 绘制相关系数热力图
        plt.figure(figsize=(12, 10))
        mask = np.triu(np.ones_like(correlation_matrix, dtype=bool))
        sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', mask=mask, vmin=-1, vmax=1)
        plt.title('比亚迪股票数据相关系数热力图')
        plt.tight_layout()
        plt.savefig('correlation_heatmap.png', dpi=300)
        print("\n相关系数热力图已保存为 correlation_heatmap.png")
        return correlation_matrix
    
    def plot_closing_price_2023(self):
        # 筛选2023年的数据
        data_2023 = self.df[self.df.index.year == 2023]
        
        # 绘制收盘价时序图
        plt.figure(figsize=(14, 7))
        plt.plot(data_2023.index, data_2023['收盘'], label='收盘价', linewidth=2, color='blue')
        
        # 添加移动平均线进行趋势分析
        data_2023['MA20'] = data_2023['收盘'].rolling(window=20).mean()
        data_2023['MA60'] = data_2023['收盘'].rolling(window=60).mean()
        plt.plot(data_2023.index, data_2023['MA20'], label='20日均线', linewidth=1.5, color='orange')
        plt.plot(data_2023.index, data_2023['MA60'], label='60日均线', linewidth=1.5, color='green')
        
        plt.title('2023年比亚迪股票收盘价时序图')
        plt.xlabel('日期')
        plt.ylabel('收盘价')
        plt.grid(True, linestyle='--', alpha=0.7)
        plt.legend()
        plt.tight_layout()
        plt.savefig('closing_price_2023.png', dpi=300)
        print("\n2023年收盘价时序图已保存为 closing_price_2023.png")
    
    def plot_k_line_chart(self):
        # 筛选2023年4月到6月的数据
        start_date = '2023-04-01'
        end_date = '2023-06-30'
        data_apr_jun = self.df[(self.df.index >= start_date) & (self.df.index <= end_date)].copy()
        
        # 确保列名符合mplfinance的要求
        data_apr_jun.rename(columns={
            '开盘': 'Open',
            '最高': 'High',
            '最低': 'Low',
            '收盘': 'Close',
            '成交量': 'Volume'
        }, inplace=True)
        
        # 绘制K线图
        plt.figure(figsize=(14, 9))
        mpf.plot(data_apr_jun, 
                 type='candle', 
                 title='2023年4月-6月比亚迪股票K线图',
                 ylabel='价格',
                 volume=True,
                 ylabel_lower='成交量',
                 show_nontrading=False,
                 style='yahoo',
                 savefig='k_line_chart_apr_jun_2023.png')
        print("\n2023年4月到6月K线图已保存为 k_line_chart_apr_jun_2023.png")
        
        # 分析K线图特征
        print("\nK线图分析:")
        print(f"- 分析期间: {start_date} 至 {end_date}")
        print(f"- 期间交易日数量: {len(data_apr_jun)}")
        print(f"- 期间最高价: {data_apr_jun['High'].max():.2f}")
        print(f"- 期间最低价: {data_apr_jun['Low'].min():.2f}")
        print(f"- 期间收盘价变化: {data_apr_jun['Close'].iloc[-1] - data_apr_jun['Close'].iloc[0]:.2f}")
        print(f"- 期间收盘价变化百分比: {(data_apr_jun['Close'].iloc[-1] / data_apr_jun['Close'].iloc[0] - 1) * 100:.2f}%")

if __name__ == "__main__":
    try:
        # 实例化分析类并执行所有分析任务
        analysis = BYDStockAnalysis('比亚迪后复权历史行情数据.xlsx')
        
        # 任务1: 读取文件，观察数据形状，输出数据前5行，并对定量变量进行描述性分析
        print("\n=== 任务1: 数据基本信息与描述性分析 ===")
        analysis.inspect_data()
        
        # 任务2: 计算变量之间的相关系数，并绘制相关系数热力图
        print("\n=== 任务2: 相关系数计算与可视化 ===")
        analysis.calculate_correlation()
        
        # 任务3: 绘制2023年全年的收盘价时序图
        print("\n=== 任务3: 2023年收盘价时序图 ===")
        analysis.plot_closing_price_2023()
        
        # 任务4: 绘制2023年4月到2023年6月的K线图，并对K线图进行分析
        print("\n=== 任务4: 2023年4-6月K线图分析 ===")
        analysis.plot_k_line_chart()
        
        print("\n所有分析任务已完成！")
    except Exception as e:
        print(f"分析过程中出现错误: {e}")